(function ($) {

    var LABB_Gallery_Helper = function ($element) {

        this._gallery = $element;

    };

    LABB_Gallery_Helper.prototype = {

        _gallery: null,

        getItemsToDisplay: function (items, paged, items_per_page) {

            var start = items_per_page * (paged - 1);

            var end = start + items_per_page;

            // send only the relevant items
            items = items.slice(start, end);

            return items;

        },

        // Manage page number display so that it does not get too long with too many page numbers displayed
        processNumberedPagination: function () {

            var maxpages = parseInt(this._gallery.data('maxpages'));

            var currentPage = parseInt(this._gallery.attr('data-current'));

            // Remove all existing dotted navigation elements
            this._gallery.find('.labb-page-nav.labb-dotted').remove();

            // proceed only if there are too many pages to display navigation for
            if (maxpages > 5) {

                var beenHiding = false;

                this._gallery.find('.labb-page-nav.labb-numbered').each(function () {

                    var page = $(this).attr('data-page'); // can return next and prev too

                    var pageNum = parseInt(page);

                    // Deal with only those pages between 1 and maxpages
                    if (pageNum > 1 && pageNum <= maxpages) {

                        var $navElement = $(this);

                        if (pageNum == currentPage || (pageNum == currentPage - 1) || (pageNum == currentPage + 1) || (pageNum == currentPage + 2)) {

                            if (beenHiding)
                                $('<a class="labb-page-nav labb-dotted" href="#" data-page="">...</a>').insertBefore($navElement);

                            $navElement.show();

                            beenHiding = false;
                        }
                        else if (pageNum == maxpages) {

                            if (beenHiding)
                                $('<a class="labb-page-nav labb-dotted" href="#" data-page="">...</a>').insertBefore($navElement);

                            beenHiding = false; // redundant for now
                        }
                        else {

                            $navElement.hide();

                            beenHiding = true;
                        }
                    }
                });
            }
        },
    };

    LABBGallery = function (settings) {
        this.nodeClass = '.fl-node-' + settings.id;
        this._init();
    };

    LABBGallery.prototype = {

        nodeClass: '',
        gallery_elem: null,

        _init: function () {

            this.gallery_elem = $(this.nodeClass).find(' .labb-gallery-wrap').eq(0);

            this._initGallery();
            this._initLightbox();

        },

        _initGallery: function () {

            if ($().isotope === undefined) {
                return;
            }

            var container = this.gallery_elem.find('.labb-gallery');
            if (container.length === 0) {
                return; // no items to filter or load and hence don't continue
            }

            var $parent = this.gallery_elem,
                settings = $parent.data('settings'),
                items = $parent.data('items'),
                maxpages = parseInt($parent.data('maxpages'));

            var gallery_helper = new LABB_Gallery_Helper(this.gallery_elem);

            // layout Isotope after all images have loaded
            var htmlContent = this.gallery_elem.find('.js-isotope');

            var isotopeOptions = htmlContent.data('isotope-options');

            htmlContent.isotope({
                // options
                itemSelector: isotopeOptions['itemSelector'],
                layoutMode: isotopeOptions['layoutMode'],
                transitionDuration: '0.8s',
                masonry: {
                    columnWidth: '.labb-grid-sizer'
                }
            });

            htmlContent.imagesLoaded(function () {
                htmlContent.isotope('layout');
            });

            // Relayout on inline full screen video and back
            $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function (e) {
                htmlContent.isotope('layout');
            });

            // Hide a few page links with dotted navigation f the number of page links crosses a certain threshold
            if (settings["pagination"] == 'paged')
                gallery_helper.processNumberedPagination();

            /* -------------- Taxonomy Filter --------------- */

            this.gallery_elem.find('.labb-taxonomy-filter .labb-filter-item a').on('click', function (e) {
                e.preventDefault();

                var selector = $(this).attr('data-value');
                container.isotope({filter: selector});
                $(this).closest('.labb-taxonomy-filter').children().removeClass('labb-active');
                $(this).closest('.labb-filter-item').addClass('labb-active');
                return false;
            });

            /* ------------------- Pagination ---------------------- */

            this.gallery_elem.find('.labb-pagination a.labb-page-nav').on('click', function (e) {
                e.preventDefault();

                var $this = $(this),
                    paged = $this.attr('data-page'),
                    current = parseInt($parent.attr('data-current'));

                // Do not continue if already processing or if the page is currently being shown
                if ($this.is('.labb-current-page') || $parent.is('.labb-processing'))
                    return;

                if (paged == 'prev') {
                    if (current <= 1)
                        return;
                    paged = current - 1;
                }
                else if (paged == 'next') {
                    if (current >= maxpages)
                        return;
                    paged = current + 1;
                }

                var items_per_page = parseInt(settings["items_per_page"]);

                var display_items = gallery_helper.getItemsToDisplay(items, paged, items_per_page);

                $parent.addClass('labb-processing');

                var data = {
                    'action': 'labb_load_gallery_items',
                    'settings': settings,
                    'items': display_items,
                    'paged': paged
                };
                // We can also pass the url value separately from ajaxurl for front end AJAX implementations
                $.post(labb_ajax_object.ajax_url, data, function (response) {

                    var $grid = $parent.find('.labb-gallery');

                    var $existing_items = $grid.children('.labb-gallery-item');

                    $grid.isotope('remove', $existing_items);

                    var $response = $('<div></div>').html(response);

                    $response.imagesLoaded(function () {

                        var $new_items = $response.children('.labb-gallery-item');

                        $grid.isotope('insert', $new_items);
                    });

                    // Set attributes of DOM elements based on page loaded
                    $parent.attr('data-current', paged);

                    $this.siblings('.labb-current-page').removeClass('labb-current-page');

                    $parent.find('.labb-page-nav[data-page="' + parseInt(paged) + '"]').addClass('labb-current-page');

                    // Once the current page is set, process the pagination links for dotted links
                    gallery_helper.processNumberedPagination();

                    $parent.find('.labb-page-nav[data-page="next"]').removeClass('labb-disabled');
                    $parent.find('.labb-page-nav[data-page="prev"]').removeClass('labb-disabled');

                    if (paged <= 1)
                        $parent.find('.labb-page-nav[data-page="prev"]').addClass('labb-disabled');
                    else if (paged >= maxpages)
                        $parent.find('.labb-page-nav[data-page="next"]').addClass('labb-disabled');

                    $parent.removeClass('labb-processing');
                });

            });


            /*---------------- Load More Button --------------------- */

            this.gallery_elem.find('.labb-pagination a.labb-load-more').on('click', function (e) {
                e.preventDefault();

                var $this = $(this),
                    current = parseInt($parent.attr('data-current')),
                    total = $parent.data('total');

                if (current >= maxpages || $parent.is('.labb-processing'))
                    return;

                $parent.addClass('labb-processing');

                var paged = current + 1;

                var items_per_page = parseInt(settings["items_per_page"]);

                var display_items = gallery_helper.getItemsToDisplay(items, paged, items_per_page);

                var data = {
                    'action': 'labb_load_gallery_items',
                    'settings': settings,
                    'items': display_items,
                    'paged': paged
                };

                // We can also pass the url value separately from ajaxurl for front end AJAX implementations
                $.post(labb_ajax_object.ajax_url, data, function (response) {

                    var $grid = $parent.find('.labb-gallery');

                    var $response = $('<div></div>').html(response);

                    $response.imagesLoaded(function () {

                        var $new_items = $response.children('.labb-gallery-item');

                        $grid.isotope('insert', $new_items);

                    });

                    $parent.attr('data-current', paged);

                    // Set remaining posts to be loaded and hide the button if we just loaded the last page
                    if (settings['show_remaining']) {
                        if (paged == maxpages) {
                            $this.find('span').text(0);
                        }
                        else {
                            var remaining = total - (paged * settings['items_per_page']);
                            $this.find('span').text(remaining);
                        }
                    }

                    if (paged == maxpages)
                        $this.addClass('labb-disabled');

                    $parent.removeClass('labb-processing');
                });

            });
        },

        _initLightbox: function () {

            if ($().fancybox === undefined) {
                return;
            }

            /* ----------------- Lightbox Support ------------------ */

            this.gallery_elem.fancybox({
                selector: 'a.labb-lightbox-item,a.labb-video-lightbox', // the selector for gallery item
                loop: true,
                buttons: [
                    "zoom",
                    "share",
                    "slideShow",
                    "fullScreen",
                    //"download",
                    "thumbs",
                    "close"
                ],
                caption: function (instance, item) {

                    var caption = $(this).attr('title') || '';

                    var description = $(this).data('description') || '';

                    if (description !== '') {
                        caption += '<div class="labb-fancybox-description">' + description + '</div>';
                    }

                    return caption;
                }
            });
        }
    };

})(jQuery);

